# -*- coding: utf-8 -*-
# @author : wanglei
# @date : 2020/5/13 2:57 PM
# @description : 矩阵
from manimlib.imports import *
from from_victor.imports import *


class MatrixDotProduct(Scene):
    '''
    矩阵点乘计算规则【矩阵的加减法都是对应位置元素的操作】
    '''
    captions=[
        '矩阵点乘也称为点积'
        '它的计算规则是',
        '对应位置的元素相乘'
        '所以也就要求这两个矩阵具有相同的行数和列数'
    ]
    def construct(self):
        matrix_text = TexMobject('\\begin{bmatrix} '
                              'a_{11} &a_{12} \\\ '
                              'a_{21} &a_{22} \\\ '
                              'a_{31} &a_{32} \\\ '
                              '\\end{bmatrix}'
                              '.'
                              '\\begin{bmatrix} '
                              'b_{11} &b_{12} \\\ '
                              'b_{21} &b_{22} \\\ '
                              'b_{31} &b_{32} \\\ '
                              '\\end{bmatrix}'
                              '=', color=WHITE)
        self.add(matrix_text)
        matrix_text.move_to(3*UP)
        self.play(Write(matrix_text))
        text = TextMobject('?', color= RED).scale(1.5)
        text.next_to(matrix_text, RIGHT)
        self.play(FadeInFromDown(text))
        self.wait(2)
        self.play(FadeOutAndShift(text))
        result_text = TexMobject('\\begin{bmatrix} '
                              'a_{11}\\times b_{11} &a_{12}\\times b_{21} \\\ '
                              'a_{21}\\times b_{21} &a_{22}\\times b_{22} \\\ '
                              'a_{31}\\times b_{31} &a_{32}\\times b_{23} \\\ '
                              '\\end{bmatrix}')
        self.play(Write(result_text.next_to(matrix_text, DOWN, aligned_edge= LEFT)))
        self.wait()
        self.play(ShowCreationThenFadeAround(matrix_text[0][2:5]),
                  ShowCreationThenFadeAround(matrix_text[0][25:28]),
                  ShowCreationThenFadeAround(result_text[0][2:9]), run_time=2)
        self.wait(2)


class MatrixProductOrigin(MovingCameraScene):
    '''
    矩阵乘法的来历和计算规则【为了方便计算，简化表达方式】（矩阵乘法也称为叉乘或叉积）
    '''
    captions = [
        '矩阵乘法的来历和计算规则',
        '矩阵乘法其实是为了简化方程组的求解'
        '这里有一个二元一次方程组'
        '求解xy等价于右边的形式'
        '我们定义第一个式子为r1'
        '第二个式子为r2'
        '那么我们利用消元法，通过三步可以得到解'
        '如果我们把式子的系数提取出，用矩阵来表示'
        '通过矩阵的乘法可以更加简便的求出方程的解'
        '矩阵乘法的计算规则就是为了方便计算规定的'
        '结果矩阵每个位置的元素就是对应第一个矩阵的行元素分别乘以第二矩阵的列元素然后求和得到'
    ]
    # captions=[
    #     '矩阵乘法的来历，矩阵乘法也称为叉乘或叉积',
    #     '矩阵乘法其实是为了简化方程组的求解'
    #     '这里有一个二元一次方程组'
    #     '求解xy等价于右边的形式'
    #     '我们定义第一个式子为r1'
    #     '第二个式子为r2'
    #     '那么我们利用消元法，通过三步可以得到解'
    #     '如果我们把式子的系数提取出，用矩阵来表示'
    #     '通过矩阵的乘法可以更加简便的求出方程的解'
    #     '矩阵乘法的计算规则就是为了方便计算规定的'
    #     '结果矩阵每个位置的元素就是对应第一个矩阵的行元素分别乘以第二矩阵的列元素然后求和得到'
    # ]

    def construct(self):
        self.camera.frame.set_width(FRAME_WIDTH)
        fx = TexMobject('\\begin{cases}'
                        '1x+2y=3 \\\ '
                        '3x+4y=5 '
                        '\\end{cases}')

        fx.move_to(3*UP + LEFT)
        self.play(Write(fx))

        fx_result1 = TexMobject('\\begin{cases}'
                        'x=? \\\ '
                        'y=? '
                        '\\end{cases}')
        fx_result1.next_to(fx, DOWN, aligned_edge=LEFT)

        equivalent = TexMobject('\\Longleftrightarrow', color = RED)
        equivalent.next_to(fx_result1, RIGHT)

        fx_result2 = TexMobject('\\begin{cases}'
                               'x+0y=? \\\ '
                               '0x+y=? '
                               '\\end{cases}')
        fx_result2.next_to(equivalent, RIGHT)
        self.play(FadeInFromDown(fx_result1))
        self.play(FadeInFromDown(equivalent))
        self.play(FadeInFromDown(fx_result2))
        self.wait(2)

        gp = VGroup(*self.get_mobjects()[1:])
        self.play(FadeOutAndShiftDown(gp))

        self.play(ShowCreationThenFadeAround(fx[0][1:8]))
        r1 = TexMobject('r_{1}', color=BLUE)
        r1.next_to(fx[0][7], RIGHT)
        self.play(FadeInFromPoint(r1, r1.get_center() + 2*RIGHT))
        self.play(ShowCreationThenFadeAround(fx[0][8:]))
        r2 = TexMobject('r_{2}', color=BLUE)
        r2.next_to(fx[0][14], RIGHT)
        self.play(FadeInFromPoint(r2,  r2.get_center() + 2*RIGHT))

        one = TextMobject('第 \\\ '
                    '一 \\\ '
                    '步 \\\ ').scale(0.7)
        one.next_to(fx, 3*LEFT +2*DOWN, aligned_edge=LEFT)
        self.play(FadeInFromLarge(one))
        step1 = TexMobject('\\begin{cases}'
                           '{r}\'_{1} = 1r_{1} \\\ '
                           '{r}\'_{2} = -3r_{1}+1r_{2}'
                           '\\end{cases}').scale(0.8)
        step1[0][1:4].set_color(BLUE)
        step1[0][6:8].set_color(BLUE)
        step1[0][8:11].set_color(BLUE)
        step1[0][14:16].set_color(BLUE)
        step1[0][18:].set_color(BLUE)
        step1.next_to(one, RIGHT)
        self.play(Write(step1))
        equivalent.scale(0.6).next_to(step1, RIGHT)
        self.play(Write(equivalent))
        step1_result = TexMobject('\\begin{cases}'
                        '1x+2y=3 \\\ '
                        '0x-2y=-4 '
                        '\\end{cases}').scale(0.8)
        step1_result.next_to(equivalent, RIGHT)
        self.play(Write(step1_result))

        two = TextMobject('第 \\\ '
                          '二 \\\ '
                          '步 \\\ ').scale(0.7)
        two.next_to(one, DOWN)
        self.play(FadeInFromLarge(two))
        step2 = TexMobject('\\begin{cases} '
                           '{r}\'_{1} = 1r_{1} \\\ '
                           '{r}\'_{2} = -\\frac{1}{2}r_{2} '
                           '\\end{cases} ').scale(0.8)

        step2[0][1:4].set_color(BLUE)
        step2[0][6:7].set_color(BLUE)
        step2[0][7:11].set_color(BLUE)
        step2[0][16:].set_color(BLUE)
        step2.next_to(two, RIGHT)
        self.play(Write(step2))
        eq_copy = equivalent.copy()
        # self.play(ApplyMethod(eq_copy.next_to, step2, 6.2*RIGHT))
        self.play(ApplyMethod(eq_copy.next_to, equivalent, 5.2*DOWN))
        step2_result = TexMobject('\\begin{cases}'
                                  '1x+2y=3 \\\ '
                                  '0x+1y=2 '
                                  '\\end{cases}').scale(0.8)
        step2_result.next_to(eq_copy, RIGHT)
        self.play(Write(step2_result))

        three = TextMobject('第 \\\ '
                          '三 \\\ '
                          '步 \\\ ').scale(0.7)
        three.next_to(two, DOWN)
        self.play(FadeInFromLarge(three))

        step3 = TexMobject('\\begin{cases}'
                           '{r}\'_{1} = 1r_{1}-2r_{2} \\\ '
                           '{r}\'_{2} = 1r_{2}'
                           '\\end{cases}').scale(0.8)
        step3[0][1:4].set_color(BLUE)
        step3[0][6:8].set_color(BLUE)
        step3[0][10:12].set_color(BLUE)
        step3[0][12:15].set_color(BLUE)
        step3[0][17:].set_color(BLUE)
        step3.next_to(three, RIGHT)
        self.play(Write(step3))
        eq_copy_copy = eq_copy.copy()
        self.play(ApplyMethod(eq_copy_copy.next_to, eq_copy, 5.2*DOWN))
        step3_result = TexMobject('\\begin{cases}'
                                  '1x+0y=-1 \\\ '
                                  '0x+1y=2 '
                                  '\\end{cases}').scale(0.8)
        step3_result.next_to(eq_copy_copy, RIGHT)
        self.play(Write(step3_result))
        self.wait(2)
        result = TexMobject('\\begin{cases}'
                                  'x=-1 \\\ '
                                  'y=2 '
                                  '\\end{cases}').scale(0.8)
        result.next_to(eq_copy_copy, RIGHT)
        self.play(Transform(step3_result, result))
        # 移动
        gp2 = VGroup(*self.get_mobjects())
        self.play(ApplyMethod(gp2.move_to, 3*UP))






        # 矩阵表示
        matrix_text = TexMobject('\\begin{bmatrix}'
                                 '1 &2 &3 \\\ '
                                 '3 &4 &5 \\\ '
                                 '\\end{bmatrix}')
        top_gp = VGroup(fx, r1, r2)
        self.play(ApplyMethod(top_gp.move_to, fx.get_center()+0.5*LEFT))
        num_gp = VGroup(fx[0][1].copy(), fx[0][4].copy(), fx[0][7].copy(), fx[0][8].copy(), fx[0][11].copy(), fx[0][14].copy())
        matrix_text.next_to(top_gp, RIGHT, buff=LARGE_BUFF)
        self.play(Transform(num_gp, matrix_text, run_time=2))
        self.wait(2)
        # 移动相机
        self.camera.frame.save_state()
        self.play(
            self.camera.frame.set_width, (step1.get_width()+one.get_width()) * 1.2,
            self.camera.frame.move_to, step1
        )
        temp1 = TexMobject('1r_{1}+0r_{2}', tex_to_color_map={'r_{1}':BLUE, 'r_{2}':BLUE}).scale(0.8)
        temp1.next_to(step1[0][4], RIGHT, buff=MED_SMALL_BUFF)
        self.play(Transform(step1[0][5:8], temp1))
        self.play(Restore(self.camera.frame))

        one_copy = one.copy()
        self.play(ApplyMethod(one_copy.next_to, three, 2*DOWN))
        matrix_result1 = TexMobject('\\begin{bmatrix}'
                                '1 &0 \\\ '
                                '-3 &1 \\\ '
                                '\\end{bmatrix}'
                                    '\\times').scale(0.8)
        matrix_result1.next_to(one_copy, RIGHT)
        one_num_gp = VGroup(temp1[0].copy(), temp1[2].copy(), step1[0][12:14].copy(), step1[0][17].copy())
        self.play(Transform(one_num_gp, matrix_result1, run_time=2))
        self.play(ApplyMethod(matrix_text.scale(0.8).next_to, matrix_result1, RIGHT))


        matrix_eq = TexMobject('\\Longleftrightarrow', color=GREEN).scale(0.6)
        matrix_eq.next_to(matrix_text, RIGHT)
        self.play(Write(matrix_eq))
        matrix_result1_2 = TexMobject('\\begin{bmatrix}'
                                      '1 &2 &3 \\\ '
                                      '0 &-2 &-4 \\\ '
                                      '\\end{bmatrix}').scale(0.8)
        matrix_result1_2.next_to(matrix_eq, RIGHT)
        self.play(Write(matrix_result1_2))

        # 移动相机
        self.camera.frame.save_state()
        self.play(
            self.camera.frame.set_width, (step1.get_width() + one.get_width()) * 1.2,
            self.camera.frame.move_to, step2
        )
        temp2 = TexMobject('1r_{1}+0r_{2}', tex_to_color_map={'r_{1}': BLUE, 'r_{2}': BLUE}).scale(0.8)
        temp3 = TexMobject('0r_{1}-\\frac{1}{2}r_{2}', tex_to_color_map={'r_{1}': BLUE, 'r_{2}': BLUE}).scale(0.8)
        temp2.next_to(step2[0][4], RIGHT, buff=MED_SMALL_BUFF)
        temp3.next_to(step2[0][11], RIGHT, buff=MED_SMALL_BUFF)
        self.play(Transform(step2[0][5:8], temp2))
        self.play(Transform(step2[0][12:], temp3))
        self.play(Restore(self.camera.frame))
        two_copy = two.copy()
        self.play(ApplyMethod(two_copy.next_to, one_copy, DOWN))

        matrix_result2 = TexMobject('\\begin{bmatrix}'
                                    '1 &0 \\\ '
                                    '0 &-\\frac{1}{2} \\\ '
                                    '\\end{bmatrix}'
                                    '\\times').scale(0.8)
        matrix_result2.next_to(two_copy, RIGHT)
        two_num_gp = VGroup(temp2[0].copy(), temp2[2].copy(), temp3[0].copy(), temp3[2].copy())
        self.play(Transform(two_num_gp, matrix_result2, run_time=2))
        matrix_result1_2_copy = matrix_result1_2.copy()
        self.play(ApplyMethod(matrix_result1_2_copy.next_to, matrix_result2, RIGHT))
        matrix_eq_copy = matrix_eq.copy()
        self.play(ApplyMethod(matrix_eq_copy.next_to, matrix_result1_2_copy, RIGHT))
        matrix_result2_2 = TexMobject('\\begin{bmatrix}'
                                      '1 &2 &3 \\\ '
                                      '0 &1 &2 \\\ '
                                      '\\end{bmatrix}').scale(0.8)

        matrix_result2_2.next_to(matrix_eq_copy, RIGHT)
        self.play(Write(matrix_result2_2))

        # 移动相机
        self.camera.frame.save_state()
        self.play(
            self.camera.frame.set_width, (step1.get_width() + one.get_width()) * 1.2,
            self.camera.frame.move_to, step3
        )
        temp4 = TexMobject('0r_{1}+1r_{2}', tex_to_color_map={'r_{1}': BLUE, 'r_{2}': BLUE}).scale(0.8)
        temp4.next_to(step3[0][15], RIGHT, buff=MED_SMALL_BUFF)
        self.play(Transform(step3[0][16:], temp4))
        self.play(Restore(self.camera.frame))
        three_copy = three.copy()
        self.play(ApplyMethod(three_copy.next_to, two_copy, DOWN))
        matrix_result3 = TexMobject('\\begin{bmatrix}'
                                    '1 &-2 \\\ '
                                    '0 &1 \\\ '
                                    '\\end{bmatrix}'
                                    '\\times').scale(0.8)
        matrix_result3.next_to(three_copy, RIGHT)
        three_num_gp = VGroup(step3[0][5].copy(), step3[0][8:10].copy(), temp4[0].copy(), temp4[2].copy())
        self.play(Transform(three_num_gp, matrix_result3, run_time=2))
        matrix_result2_2_copy = matrix_result2_2.copy()
        self.play(ApplyMethod(matrix_result2_2_copy.next_to, matrix_result3, RIGHT))
        matrix_eq_copy_copy = matrix_eq_copy.copy()
        self.play(ApplyMethod(matrix_eq_copy_copy.next_to, matrix_result2_2_copy, RIGHT))
        matrix_result3_2 = TexMobject('\\begin{bmatrix}'
                                      '1 &0 &-1 \\\ '
                                      '0 &1 &2 \\\ '
                                      '\\end{bmatrix}').scale(0.8)
        matrix_result3_2.next_to(matrix_eq_copy_copy, RIGHT)
        self.play(Write(matrix_result3_2))
        # 简写
        simple = TextMobject('合 \\\ '
                            '并 \\\ ').scale(0.7)
        simple.next_to(three_copy, DOWN)
        self.play(Write(simple))
        matrix_simple1 = TexMobject('\\begin{bmatrix}'
                                '1 &-2 \\\ '
                                '0 &1 \\\ '
                                '\\end{bmatrix}'
                                    '\\times'
                                '\\begin{bmatrix}'
                                '1 &0 \\\ '
                                '0 &-\\frac{1}{2} \\\ '
                                '\\end{bmatrix}'
                                    '\\times'
                                '\\begin{bmatrix}'
                                '1 &0 \\\ '
                                '-3 &1 \\\ '
                                '\\end{bmatrix}'
                                    '\\times'
                                '\\begin{bmatrix}'
                                '1 &2 &3 \\\ '
                                '3 &4 &5 \\\ '
                                '\\end{bmatrix}').scale(0.7)
        matrix_simple1.next_to(simple, RIGHT)
        self.play(Write(matrix_simple1, run_time=2))
        matrix_simple2 = TexMobject(     '='
                               '\\begin{bmatrix}'
                               '1 &0 &-1 \\\ '
                               '0 &1 &2 \\\ '
                               '\\end{bmatrix}').scale(0.7)
        matrix_simple2.next_to(matrix_simple1, DOWN, aligned_edge=LEFT)
        self.play(Write(matrix_simple2))
        """
        matrix_text = TexMobject('\\begin{bmatrix} '
                              'a_{11} &a_{12} &a_{13}\\\ '
                              'a_{21} &a_{22} &a_{23}\\\ '
                              '\\end{bmatrix}'
                              '\\times'
                              '\\begin{bmatrix} '
                              'b_{11} &b_{12} \\\ '
                              'b_{21} &b_{22} \\\ '
                              'b_{31} &b_{32} \\\ '
                              '\\end{bmatrix}'
                              '='
                              '', color=WHITE).scale(0.9)
        self.add(matrix_text)
        matrix_text.move_to(0.2*LEFT + 3 * UP)
        self.play(Write(matrix_text))
        text = TextMobject('?', color=RED).scale(1.5)
        text.next_to(matrix_text, RIGHT)
        self.play(FadeInFromDown(text))
        self.wait(2)
        result_text = TexMobject('\\begin{bmatrix} '
                                 'a_{11} b_{11}+a_{12} b_{21}+a_{13} b_{31}'
                                 '&a_{11} b_{12}+a_{12} b_{22}+a_{12} b_{32} \\\ '
                                 'a_{21} b_{11}+a_{22} b_{21}+a_{23} b_{31}'
                                 '&a_{21} b_{12}+a_{22} b_{22}+a_{23} b_{32} \\\ '
                                 '\\end{bmatrix}').scale(0.7)
        self.play(Write(result_text, run_time=2))
        """